{
 "cells": [
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-26T07:45:33.513231Z",
     "start_time": "2025-09-26T07:45:33.509305Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 直接使用文件名（文件必须在当前工作目录）\n",
    "content = ''\n",
    "with open('rag_data.txt', 'r', encoding='utf-8') as file:\n",
    "    content = file.read()\n",
    "\n",
    "\n",
    "# chunk\n",
    "from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
    "text_splitter = RecursiveCharacterTextSplitter(\n",
    "    chunk_size=1000, chunk_overlap=200, add_start_index=True\n",
    ")\n",
    "all_splits = text_splitter.split_text(content)\n",
    "print(\"一共划分成 %s 个chunk\" % len(all_splits))\n",
    "\n",
    "\n",
    "\n"
   ],
   "id": "ff42038550b3c313",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "一共划分成 7 个chunk\n"
     ]
    }
   ],
   "execution_count": 22
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 向量存储\n",
   "id": "80c420e280583c30"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-26T07:45:34.156654Z",
     "start_time": "2025-09-26T07:45:33.537254Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 存储\n",
    "from langchain_chroma import Chroma\n",
    "from langchain_community.embeddings import DashScopeEmbeddings\n",
    "\n",
    "embeddings = DashScopeEmbeddings(\n",
    "    dashscope_api_key=\"sk-a5985cc3833b4e63a980cd9914904ab0\",\n",
    "    model=\"text-embedding-v1\",\n",
    ")\n",
    "vectorstore = Chroma.from_texts(\n",
    "    all_splits,\n",
    "    embedding=embeddings,\n",
    "    persist_directory=\"./chroma_db\",\n",
    ")\n"
   ],
   "id": "89512d9307e263c7",
   "outputs": [],
   "execution_count": 24
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 检索与生成：检索",
   "id": "c9f7e2d41b53c2e7"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-26T07:45:34.411749Z",
     "start_time": "2025-09-26T07:45:34.162502Z"
    }
   },
   "cell_type": "code",
   "source": [
    "\n",
    "#  检索与生成: 检索\n",
    "retriever = vectorstore.as_retriever(search_type=\"similarity\", search_kwargs={\"k\": 6})\n",
    "retrieved_docs = retriever.invoke(\"说说Python的缺点？\")\n",
    "print('-' * 100)\n",
    "len(retrieved_docs)\n",
    "print(retrieved_docs)\n",
    "print(retrieved_docs[0].page_content)\n"
   ],
   "id": "c02efd6407871531",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------------------------------------------------------------------------------------------------\n",
      "[Document(id='219a8312-5365-4e9b-a381-8cba2e4843f1', metadata={}, page_content='另外就是把其他语言开发的程序再包装起来，方便使用。\\n最后说说Python的缺点。\\n任何编程语言都有缺点，Python也不例外。优点说过了，那Python有哪些缺点呢？\\n第一个缺点就是运行速度慢，和C程序相比非常慢，因为Python是解释型语言，你的代码在执行时会一行一行地翻译成CPU能理解的机器码，这个翻译过程非常耗时，所以很慢。而C程序是运行前直接编译成CPU能执行的机器码，所以非常快。'), Document(id='c6020381-d504-402f-88fc-9ec8238924be', metadata={}, page_content='总的来说，Python的哲学就是简单优雅，尽量写容易看明白的代码，尽量写少的代码。如果一个资深程序员向你炫耀他写的晦涩难懂、动不动就几万行的代码，你可以尽情地嘲笑他。\\n那Python适合开发哪些类型的应用呢？\\n首选是网络应用，包括网站、后台服务等等；\\n其次是许多日常需要的小工具，包括系统管理员需要的脚本任务等等；\\n另外就是把其他语言开发的程序再包装起来，方便使用。\\n最后说说Python的缺点。\\n任何编程语言都有缺点，Python也不例外。优点说过了，那Python有哪些缺点呢？\\n第一个缺点就是运行速度慢，和C程序相比非常慢，因为Python是解释型语言，你的代码在执行时会一行一行地翻译成CPU能理解的机器码，这个翻译过程非常耗时，所以很慢。而C程序是运行前直接编译成CPU能执行的机器码，所以非常快。\\n但是大量的应用程序不需要这么快的运行速度，因为用户根本感觉不出来。例如开发一个下载MP3的网络应用程序，C程序的运行时间需要0.001秒，而Python程序的运行时间需要0.1秒，慢了100倍，但由于网络更慢，需要等待1秒，你想，用户能感觉到1.001秒和1.1秒的区别吗？这就好比F1赛车和普通的出租车在北京三环路上行驶的道理一样，虽然F1赛车理论时速高达400公里，但由于三环路堵车的时速只有20公里，因此，作为乘客，你感觉的时速永远是20公里。\\n不要在意程序运行速度\\n第二个缺点就是代码不能加密。如果要发布你的Python程序，实际上就是发布源代码，这一点跟C语言不同，C语言不用发布源代码，只需要把编译后的机器码（也就是你在Windows上常见的xxx.exe文件）发布出去。要从机器码反推出C代码是不可能的，所以，凡是编译型的语言，都没有这个问题，而解释型的语言，则必须把源码发布出去。\\n这个缺点仅限于你要编写的软件需要卖给别人挣钱的时候。好消息是目前的互联网时代，靠卖软件授权的商业模式越来越少了，靠网站和移动应用卖服务的模式越来越多了，后一种模式不需要把源码给别人。\\n再说了，现在如火如荼的开源运动和互联网自由开放的精神是一致的，互联网上有无数非常优秀的像Linux一样的开源代码，我们千万不要高估自己写的代码真的有非常大的“商业价值”。那些大公司的代码不愿意开放的更重要的原因是代码写得太烂了，一旦开源，就没人敢用他们的产品了。\\n哪有功夫破解你的烂代码'), Document(id='29043bc2-fab0-4fb3-9a0b-ffc8ff17f190', metadata={}, page_content='总的来说，Python的哲学就是简单优雅，尽量写容易看明白的代码，尽量写少的代码。如果一个资深程序员向你炫耀他写的晦涩难懂、动不动就几万行的代码，你可以尽情地嘲笑他。\\n那Python适合开发哪些类型的应用呢？\\n首选是网络应用，包括网站、后台服务等等；\\n其次是许多日常需要的小工具，包括系统管理员需要的脚本任务等等；\\n另外就是把其他语言开发的程序再包装起来，方便使用。\\n最后说说Python的缺点。\\n任何编程语言都有缺点，Python也不例外。优点说过了，那Python有哪些缺点呢？\\n第一个缺点就是运行速度慢，和C程序相比非常慢，因为Python是解释型语言，你的代码在执行时会一行一行地翻译成CPU能理解的机器码，这个翻译过程非常耗时，所以很慢。而C程序是运行前直接编译成CPU能执行的机器码，所以非常快。\\n但是大量的应用程序不需要这么快的运行速度，因为用户根本感觉不出来。例如开发一个下载MP3的网络应用程序，C程序的运行时间需要0.001秒，而Python程序的运行时间需要0.1秒，慢了100倍，但由于网络更慢，需要等待1秒，你想，用户能感觉到1.001秒和1.1秒的区别吗？这就好比F1赛车和普通的出租车在北京三环路上行驶的道理一样，虽然F1赛车理论时速高达400公里，但由于三环路堵车的时速只有20公里，因此，作为乘客，你感觉的时速永远是20公里。\\n不要在意程序运行速度\\n第二个缺点就是代码不能加密。如果要发布你的Python程序，实际上就是发布源代码，这一点跟C语言不同，C语言不用发布源代码，只需要把编译后的机器码（也就是你在Windows上常见的xxx.exe文件）发布出去。要从机器码反推出C代码是不可能的，所以，凡是编译型的语言，都没有这个问题，而解释型的语言，则必须把源码发布出去。\\n这个缺点仅限于你要编写的软件需要卖给别人挣钱的时候。好消息是目前的互联网时代，靠卖软件授权的商业模式越来越少了，靠网站和移动应用卖服务的模式越来越多了，后一种模式不需要把源码给别人。\\n再说了，现在如火如荼的开源运动和互联网自由开放的精神是一致的，互联网上有无数非常优秀的像Linux一样的开源代码，我们千万不要高估自己写的代码真的有非常大的“商业价值”。那些大公司的代码不愿意开放的更重要的原因是代码写得太烂了，一旦开源，就没人敢用他们的产品了。\\n哪有功夫破解你的烂代码'), Document(id='88115a68-4a14-4ff1-877d-7e6252d3f258', metadata={}, page_content='总的来说，Python的哲学就是简单优雅，尽量写容易看明白的代码，尽量写少的代码。如果一个资深程序员向你炫耀他写的晦涩难懂、动不动就几万行的代码，你可以尽情地嘲笑他。\\n那Python适合开发哪些类型的应用呢？\\n首选是网络应用，包括网站、后台服务等等；\\n其次是许多日常需要的小工具，包括系统管理员需要的脚本任务等等；\\n另外就是把其他语言开发的程序再包装起来，方便使用。\\n最后说说Python的缺点。\\n任何编程语言都有缺点，Python也不例外。优点说过了，那Python有哪些缺点呢？\\n第一个缺点就是运行速度慢，和C程序相比非常慢，因为Python是解释型语言，你的代码在执行时会一行一行地翻译成CPU能理解的机器码，这个翻译过程非常耗时，所以很慢。而C程序是运行前直接编译成CPU能执行的机器码，所以非常快。\\n但是大量的应用程序不需要这么快的运行速度，因为用户根本感觉不出来。例如开发一个下载MP3的网络应用程序，C程序的运行时间需要0.001秒，而Python程序的运行时间需要0.1秒，慢了100倍，但由于网络更慢，需要等待1秒，你想，用户能感觉到1.001秒和1.1秒的区别吗？这就好比F1赛车和普通的出租车在北京三环路上行驶的道理一样，虽然F1赛车理论时速高达400公里，但由于三环路堵车的时速只有20公里，因此，作为乘客，你感觉的时速永远是20公里。\\n不要在意程序运行速度\\n第二个缺点就是代码不能加密。如果要发布你的Python程序，实际上就是发布源代码，这一点跟C语言不同，C语言不用发布源代码，只需要把编译后的机器码（也就是你在Windows上常见的xxx.exe文件）发布出去。要从机器码反推出C代码是不可能的，所以，凡是编译型的语言，都没有这个问题，而解释型的语言，则必须把源码发布出去。\\n这个缺点仅限于你要编写的软件需要卖给别人挣钱的时候。好消息是目前的互联网时代，靠卖软件授权的商业模式越来越少了，靠网站和移动应用卖服务的模式越来越多了，后一种模式不需要把源码给别人。\\n再说了，现在如火如荼的开源运动和互联网自由开放的精神是一致的，互联网上有无数非常优秀的像Linux一样的开源代码，我们千万不要高估自己写的代码真的有非常大的“商业价值”。那些大公司的代码不愿意开放的更重要的原因是代码写得太烂了，一旦开源，就没人敢用他们的产品了。\\n哪有功夫破解你的烂代码'), Document(id='f9fce719-e8b4-4154-b7d3-4c04298de2b8', metadata={}, page_content='总的来说，Python的哲学就是简单优雅，尽量写容易看明白的代码，尽量写少的代码。如果一个资深程序员向你炫耀他写的晦涩难懂、动不动就几万行的代码，你可以尽情地嘲笑他。\\n那Python适合开发哪些类型的应用呢？\\n首选是网络应用，包括网站、后台服务等等；\\n其次是许多日常需要的小工具，包括系统管理员需要的脚本任务等等；\\n另外就是把其他语言开发的程序再包装起来，方便使用。\\n最后说说Python的缺点。\\n任何编程语言都有缺点，Python也不例外。优点说过了，那Python有哪些缺点呢？\\n第一个缺点就是运行速度慢，和C程序相比非常慢，因为Python是解释型语言，你的代码在执行时会一行一行地翻译成CPU能理解的机器码，这个翻译过程非常耗时，所以很慢。而C程序是运行前直接编译成CPU能执行的机器码，所以非常快。\\n但是大量的应用程序不需要这么快的运行速度，因为用户根本感觉不出来。例如开发一个下载MP3的网络应用程序，C程序的运行时间需要0.001秒，而Python程序的运行时间需要0.1秒，慢了100倍，但由于网络更慢，需要等待1秒，你想，用户能感觉到1.001秒和1.1秒的区别吗？这就好比F1赛车和普通的出租车在北京三环路上行驶的道理一样，虽然F1赛车理论时速高达400公里，但由于三环路堵车的时速只有20公里，因此，作为乘客，你感觉的时速永远是20公里。\\n不要在意程序运行速度\\n第二个缺点就是代码不能加密。如果要发布你的Python程序，实际上就是发布源代码，这一点跟C语言不同，C语言不用发布源代码，只需要把编译后的机器码（也就是你在Windows上常见的xxx.exe文件）发布出去。要从机器码反推出C代码是不可能的，所以，凡是编译型的语言，都没有这个问题，而解释型的语言，则必须把源码发布出去。\\n这个缺点仅限于你要编写的软件需要卖给别人挣钱的时候。好消息是目前的互联网时代，靠卖软件授权的商业模式越来越少了，靠网站和移动应用卖服务的模式越来越多了，后一种模式不需要把源码给别人。\\n再说了，现在如火如荼的开源运动和互联网自由开放的精神是一致的，互联网上有无数非常优秀的像Linux一样的开源代码，我们千万不要高估自己写的代码真的有非常大的“商业价值”。那些大公司的代码不愿意开放的更重要的原因是代码写得太烂了，一旦开源，就没人敢用他们的产品了。\\n哪有功夫破解你的烂代码'), Document(id='8f73ee0f-305e-4537-a5f2-f37705c46b03', metadata={}, page_content='总的来说，Python的哲学就是简单优雅，尽量写容易看明白的代码，尽量写少的代码。如果一个资深程序员向你炫耀他写的晦涩难懂、动不动就几万行的代码，你可以尽情地嘲笑他。\\n那Python适合开发哪些类型的应用呢？\\n首选是网络应用，包括网站、后台服务等等；\\n其次是许多日常需要的小工具，包括系统管理员需要的脚本任务等等；\\n另外就是把其他语言开发的程序再包装起来，方便使用。\\n最后说说Python的缺点。\\n任何编程语言都有缺点，Python也不例外。优点说过了，那Python有哪些缺点呢？\\n第一个缺点就是运行速度慢，和C程序相比非常慢，因为Python是解释型语言，你的代码在执行时会一行一行地翻译成CPU能理解的机器码，这个翻译过程非常耗时，所以很慢。而C程序是运行前直接编译成CPU能执行的机器码，所以非常快。\\n但是大量的应用程序不需要这么快的运行速度，因为用户根本感觉不出来。例如开发一个下载MP3的网络应用程序，C程序的运行时间需要0.001秒，而Python程序的运行时间需要0.1秒，慢了100倍，但由于网络更慢，需要等待1秒，你想，用户能感觉到1.001秒和1.1秒的区别吗？这就好比F1赛车和普通的出租车在北京三环路上行驶的道理一样，虽然F1赛车理论时速高达400公里，但由于三环路堵车的时速只有20公里，因此，作为乘客，你感觉的时速永远是20公里。\\n不要在意程序运行速度\\n第二个缺点就是代码不能加密。如果要发布你的Python程序，实际上就是发布源代码，这一点跟C语言不同，C语言不用发布源代码，只需要把编译后的机器码（也就是你在Windows上常见的xxx.exe文件）发布出去。要从机器码反推出C代码是不可能的，所以，凡是编译型的语言，都没有这个问题，而解释型的语言，则必须把源码发布出去。\\n这个缺点仅限于你要编写的软件需要卖给别人挣钱的时候。好消息是目前的互联网时代，靠卖软件授权的商业模式越来越少了，靠网站和移动应用卖服务的模式越来越多了，后一种模式不需要把源码给别人。\\n再说了，现在如火如荼的开源运动和互联网自由开放的精神是一致的，互联网上有无数非常优秀的像Linux一样的开源代码，我们千万不要高估自己写的代码真的有非常大的“商业价值”。那些大公司的代码不愿意开放的更重要的原因是代码写得太烂了，一旦开源，就没人敢用他们的产品了。\\n哪有功夫破解你的烂代码')]\n",
      "另外就是把其他语言开发的程序再包装起来，方便使用。\n",
      "最后说说Python的缺点。\n",
      "任何编程语言都有缺点，Python也不例外。优点说过了，那Python有哪些缺点呢？\n",
      "第一个缺点就是运行速度慢，和C程序相比非常慢，因为Python是解释型语言，你的代码在执行时会一行一行地翻译成CPU能理解的机器码，这个翻译过程非常耗时，所以很慢。而C程序是运行前直接编译成CPU能执行的机器码，所以非常快。\n"
     ]
    }
   ],
   "execution_count": 25
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 检索与生成：生成",
   "id": "7f36dd049894deda"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-26T07:45:35.052153Z",
     "start_time": "2025-09-26T07:45:34.416630Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_community.chat_models import ChatOpenAI\n",
    "\n",
    "# 使用 DeepSeek 的兼容 OpenAI 接口\n",
    "llm = ChatOpenAI(\n",
    "    model=\"deepseek-chat\",\n",
    "    base_url=\"https://api.deepseek.com/v1\",  # DeepSeek 的 OpenAI 兼容接口\n",
    "    api_key=\"sk-a76a85b93093439ba3dc5b6dedfc51e5\",\n",
    "    temperature=0,\n",
    "    max_tokens=2048,\n",
    ")\n",
    "\n",
    "# 我们将使用一个用于 RAG 的提示，该提示已检查到 LangChain 提示中心\n",
    "from langchain import hub\n",
    "\n",
    "prompt = hub.pull(\"rlm/rag-prompt\")\n",
    "\n",
    "example_messages = prompt.invoke(\n",
    "    {\"context\": \"filler context\", \"question\": \"filler question\"}\n",
    ").to_messages()\n",
    "print(example_messages[0].content)\n",
    "\n"
   ],
   "id": "166db55084ce558d",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "F:\\tool_software\\anaconda\\envs\\langchain_demo\\Lib\\site-packages\\langsmith\\client.py:272: LangSmithMissingAPIKeyWarning: API key must be provided when using hosted LangSmith API\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.\n",
      "Question: filler question \n",
      "Context: filler context \n",
      "Answer:\n"
     ]
    }
   ],
   "execution_count": 26
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "#### 我们将使用 LCEL 可运行接口 协议来定义链，允许我们\n",
    "\n",
    "- 以透明的方式将组件和函数连接在一起\n",
    "- 自动追踪我们在 LangSmith 中的链\n",
    "- 开箱即用地获得流式、异步和批量调用。"
   ],
   "id": "32435a082a1c65bc"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-26T07:50:39.681243Z",
     "start_time": "2025-09-26T07:50:33.342516Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# <!--IMPORTS:[{\"imported\": \"StrOutputParser\", \"source\": \"langchain_core.output_parsers\", \"docs\": \"https://python.langchain.com/api_reference/core/output_parsers/langchain_core.output_parsers.string.StrOutputParser.html\", \"title\": \"Build a Retrieval Augmented Generation (RAG) App\"}, {\"imported\": \"RunnablePassthrough\", \"source\": \"langchain_core.runnables\", \"docs\": \"https://python.langchain.com/api_reference/core/runnables/langchain_core.runnables.passthrough.RunnablePassthrough.html\", \"title\": \"Build a Retrieval Augmented Generation (RAG) App\"}]-->\n",
    "from langchain_core.output_parsers import StrOutputParser\n",
    "from langchain_core.runnables import RunnablePassthrough\n",
    "\n",
    "def format_docs(docs):\n",
    "    return \"\\n\\n\".join(doc.page_content for doc in docs)\n",
    "\n",
    "rag_chain = (\n",
    "    {\"context\": retriever | format_docs, \"question\": RunnablePassthrough()} | prompt | llm | StrOutputParser()\n",
    ")\n",
    "\n",
    "# for chunk in rag_chain.stream(\"你是谁\"):\n",
    "for chunk in rag_chain.stream(\"python简介\"):\n",
    "    print(chunk, end=\"\", flush=True)"
   ],
   "id": "78547d16d940d4ed",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Python是一种高级、优雅、明确且简单的计算机程序设计语言。它以其代码简洁易懂而著称，非常适合初学者入门和完成日常任务。Python应用广泛，可用于开发网站（如YouTube、豆瓣）、自动化脚本以及网络游戏后台等众多领域。"
     ]
    }
   ],
   "execution_count": 30
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-26T07:45:40.731110Z",
     "start_time": "2025-09-26T07:45:40.729142Z"
    }
   },
   "cell_type": "code",
   "source": "",
   "id": "1d86e1bc8f3e1ece",
   "outputs": [],
   "execution_count": null
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
